﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;

namespace SHomeWorkshop.LunarMind.Commands
{
    /// <summary>
    /// 以此类为模板，制作自定义命令类
    ///     共需要修改１０处！！！
    /// ==============================
    /// 
    /// 复制命令。
    /// ★①，修改类名。
    /// </summary>
    public static class CopyCommand
    {
        private static RoutedUICommand routedUICmd;//创建私有字段

        public static RoutedUICommand RoutedUICmd//创建只读静态属性
        {
            get { return routedUICmd; }
        }

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static CopyCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand("CopyCommand", "CopyCommand",
                typeof(CopyCommand),//创建RoutedUICommand对象
                new InputGestureCollection() 
                { 
                    //★⑤，修改此处两个参数，以便挂接快捷键。
                    new KeyGesture(Key.C,ModifierKeys.Control,"Ctrl+C")
                });

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        private static CommandBinding cmdBinding = new CommandBinding();

        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。

            Copy();
        }

        /// <summary>
        /// 此方法是调用DeleteCommand的Delete来实现。
        /// </summary>
        internal static void Copy()
        {
            if (Globals.MainWindow.SelectedComment != null)
            {
                CopyComment(Globals.MainWindow.SelectedComment); return;
            }

            if (Globals.MainWindow.SelectedRelation != null)
            {
                CopyRelation(Globals.MainWindow.SelectedRelation); return;
            }

            if (Globals.MainWindow.SelectedPictureBox != null)
            {
                CopyPictureBox(Globals.MainWindow.SelectedPictureBox); return;
            }

            if (Globals.MainWindow.SelectedTitleImage != null)
            {
                CopyTitleImage(Globals.MainWindow.SelectedTitleImage); return;
            }

            #region 检查是否同一阶（因为可能在其它地方调用，所以光靠CanExecute检测是不行的。

            //if (Globals.MainWindow.SelectedTitlesList.Contains(Globals.MainWindow.RootTitle))
            //{
            //    MessageBox.Show("根标题不允许进行[剪切、复制、粘贴、删除]等操作。",
            //        Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            //    return;
            //}

            bool sameLevel = false;

            if (Globals.MainWindow.SelectedTitlesList.Count == 1)
            {
                sameLevel = true;
            }
            else
            {
                Title fstTitle = Globals.MainWindow.SelectedTitlesList[0];

                bool sameHigerID = true;

                for (int i = 1; i < Globals.MainWindow.SelectedTitlesList.Count; i++)
                {
                    Title t = Globals.MainWindow.SelectedTitlesList[i];
                    if (t.HigherLevelTitleID != fstTitle.HigherLevelTitleID)
                    {
                        sameHigerID = false; break;
                    }
                }

                sameLevel = sameHigerID;//只允许同阶剪切。
            }
            #endregion

            if (sameLevel == false)
            {
                MessageBox.Show("[剪切、删除、复制、粘贴]这几个操作在选取多个标题时，这些标题必须是同一级。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Globals.MainWindow.SelectedTitlesList.Sort(Title.titleIndexSortter);//按Index排序。

            StringBuilder sbTitles = new StringBuilder();
            StringBuilder sbComments = new StringBuilder();
            StringBuilder sbPictureBoxes = new StringBuilder();

            sbTitles.Append("<Titles>");

            for (int i = Globals.MainWindow.SelectedTitlesList.Count - 1; i >= 0; i--)
            {
                CopyTitle(Globals.MainWindow.SelectedTitlesList[i], sbTitles);
            }

            sbTitles.Append("</Titles>");

            string strTitles = sbTitles.ToString();

            sbComments.Append("<Comments>");
            sbPictureBoxes.Append("<PictureBoxes>");
            foreach (UIElement ue in Globals.MainWindow.mainCanvas.Children)
            {
                Comment c = ue as Comment;
                if (c != null)
                {
                    if (strTitles.Contains(c.MasterTitleID))
                    {
                        sbComments.Append(c.XmlData.OuterXml);
                    }
                }
                else
                {
                    PictureBox p = ue as PictureBox;
                    if (p != null)
                    {
                        if (strTitles.Contains(p.MasterTitleID))
                        {
                            sbPictureBoxes.Append(p.XmlData.OuterXml);
                        }
                    }
                }
            }
            sbComments.Append("</Comments>");
            sbPictureBoxes.Append("</PictureBoxes>");

            Clipboard.SetData(DataFormats.UnicodeText,
                "<LunarMind.Copy>" +
                strTitles +
                sbComments.ToString() +
                sbPictureBoxes.ToString() +
                "</LunarMind.Copy>");
        }

        private static void CopyComment(Comment comment)
        {
            if (comment == null) return;

            Clipboard.SetData(DataFormats.UnicodeText,
                "<LunarMind.Comment>" +
                comment.XmlData.OuterXml +
                "</LunarMind.Comment>");
        }

        private static void CopyRelation(Relation relation)
        {
            if (relation == null) return;

            Clipboard.SetData(DataFormats.UnicodeText,
                "<LunarMind.Relation>" +
                relation.XmlData.OuterXml +
                "</LunarMind.Relation>");
        }

        private static void CopyPictureBox(PictureBox pictureBox)
        {
            if (pictureBox == null) return;

            Clipboard.SetData(DataFormats.UnicodeText,
                 "<LunarMind.PictureBox>" +
                 pictureBox.XmlData.OuterXml +
                 "</LunarMind.PictureBox>");
        }

        private static void CopyTitleImage(TitleImage titleImage)
        {
            if (titleImage == null) return;

            Clipboard.SetData(DataFormats.UnicodeText,
                 "<LunarMind.TitleImage>" +
                 titleImage.XmlData.OuterXml +
                 "</LunarMind.TitleImage>");
        }

        /// <summary>
        /// 递归复制公式的Xml文本到StringBuilder缓冲区中。
        /// </summary>
        /// <param name="title"></param>
        /// <param name="sb"></param>
        private static void CopyTitle(Title title, StringBuilder sb)
        {
            if (title == null) return;

            List<Title> lowerTitles = title.GetLowerLevelTitles();

            if (lowerTitles.Count >= 0)
            {
                for (int i = lowerTitles.Count - 1; i >= 0; i--)
                {
                    Title t = lowerTitles[i];
                    CopyTitle(t, sb);
                }
            }

            //这里要去掉关系线。剪切、复制、粘贴时，不能连关系线一并粘贴，不然就全乱套了。
            XmlNode relationSetNode = title.XmlData.SelectSingleNode("RelationSet");
            if (relationSetNode != null)
            {
                XmlDocument tmpDoc = new XmlDocument();
                StringBuilder tmpStringBuilder = new StringBuilder();
                tmpStringBuilder.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                tmpStringBuilder.Append(title.XmlData.OuterXml);
                tmpDoc.LoadXml(tmpStringBuilder.ToString());

                XmlNode newRelationSetNode = tmpDoc.DocumentElement.SelectSingleNode("RelationSet");
                if (newRelationSetNode != null)
                {
                    tmpDoc.DocumentElement.RemoveChild(newRelationSetNode);
                }

                sb.Append(tmpDoc.DocumentElement.OuterXml);
            }
            else
            {
                sb.Append(title.XmlData.OuterXml);
            }
        }

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。
            if (Globals.MainWindow.SelectedTitlesList.Count <= 0)
            {
                if (Globals.MainWindow.SelectedComment != null)
                {
                    e.CanExecute = true; return;
                }

                if (Globals.MainWindow.SelectedPictureBox != null)
                {
                    e.CanExecute = true; return;
                }

                if (Globals.MainWindow.SelectedTitleImage != null)
                {
                    e.CanExecute = true; return;
                }

                if (Globals.MainWindow.SelectedRelation != null)
                {
                    e.CanExecute = true; return;
                }

                e.CanExecute = false;
                return;
            }
            else
            {
                //if (Globals.MainWindow.SelectedTitlesList.Contains(Globals.MainWindow.RootTitle))
                //{
                //    e.CanExecute = false;//根标题不允许剪切、复制、粘贴、删除。
                //    return;
                //}

                //检查是否同一阶
                if (Globals.MainWindow.SelectedTitlesList.Count == 1)
                {
                    e.CanExecute = true;
                }
                else
                {
                    Title fstTitle = Globals.MainWindow.SelectedTitlesList[0];

                    bool sameHigerID = true;

                    for (int i = 1; i < Globals.MainWindow.SelectedTitlesList.Count; i++)
                    {
                        Title t = Globals.MainWindow.SelectedTitlesList[i];
                        if (t.HigherLevelTitleID != fstTitle.HigherLevelTitleID)
                        {
                            sameHigerID = false; break;
                        }
                    }

                    e.CanExecute = sameHigerID;//只允许同阶剪切。
                }
            }
        }
    }
}
